package com.bdcom.listener;

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.bdcom.comp.CanvasPanel;
import com.bdcom.comp.DevicePopUpMenu;
import com.bdcom.comp.InfoBarPanel;
import com.bdcom.comp.ToolBarPanel;
import com.bdcom.model.AbstractBarrier;
import com.bdcom.model.AbstractDevice;
import com.bdcom.model.IBarrier;
import com.bdcom.model.IDevice;
import com.bdcom.util.PlannerUtil;

@Component
public class CanvasMouseListener extends MouseAdapter {

	@Autowired
	private CanvasPanel canvasPanel;
	@Autowired
	private InfoBarPanel infoBarPanel;
	@Autowired
	private ToolBarPanel toolBarPanel;
	@Autowired
	private DevicePopUpMenu deviePopUpMenu;

	private ListenerCommand listenerCommand = ListenerCommand.NONE;

	private Point oldPoint;

	private Point newPoint;

	public CanvasMouseListener() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		super.mouseClicked(e);

		if (canvasPanel.getCanvasModel() == null) {
			return;
		}
		// 右键
		if (e.isMetaDown()) {
			// 根据事件判断右键如何处理
			switch (listenerCommand) {
			case ADDDEVICE:
				toolBarPanel.clickaddDeviceMenu();
				break;
			case ADDLINE:
				toolBarPanel.clickaddLineMenu();
				break;
			case ADDCURVE:
				toolBarPanel.clickaddCurveMenu();
				break;
			case ADDRECT:
				toolBarPanel.clickaddRectMenu();
				break;
			case ADDELLIPSE:
				toolBarPanel.clickaddEllipseMenu();
				break;
			case NONE: {
				doPopUpMenuEvent(e.getPoint());
			}
				break;
			default:
				break;
			}

			return;
		}

		// 左键
		Point point = e.getPoint();

		double roomPercent = canvasPanel.getCanvasModel().getRoomPercent();

		point.setLocation(point.getX() / roomPercent, point.getY() / roomPercent);

		switch (listenerCommand) {

		case ADDDEVICE: {

			canvasPanel.addDevice(point);

		}
			break;
		case ADDLINE: {
			doAddLineCase(e.getClickCount(), point);
		}
			break;
		case ADDCURVE: {
			doAddCurveCase(e.getClickCount(), point);
		}
			break;
		case ADDRECT: {
			doAddRectCase(point);
		}
			break;
		case ADDELLIPSE: {
			doAddEllipse(point);
		}
			break;
		case NONE: {
			doNoneCase(e.getClickCount(), point);
		}
			canvasPanel.repaint();
			break;
		default:
			break;
		}

	}

	private void doAddCurveCase(int clickCount, Point point) {
		// TODO Auto-generated method stub
		switch (clickCount) {
		case 1:
			canvasPanel.addTempPoint(point);
			break;
		case 2:
			canvasPanel.addCurve();
			break;
		default:
			break;
		}
	}

	private void doNoneCase(int clickCount, Point point) {
		// TODO Auto-generated method stub

		switch (clickCount) {

		case 1: {
			// 点击事件为1时，先清空一下零时数据。
			canvasPanel.clearTempDatas();

			boolean find = false;

			for (IDevice device : canvasPanel.getCanvasModel().getDevs()) {

				if (device.containsPoint(point)) {

					canvasPanel.setSelectedObject(device);

					find = true;

					break;
				}
			}

			if (!find) {

				for (IBarrier barrier : canvasPanel.getCanvasModel().getBarriers()) {

					if (barrier.containsPoint(point)) {

						canvasPanel.setSelectedObject(barrier);

						break;
					}
				}
			}
		}
			break;
		case 2: {

			Object selectedObj = canvasPanel.getSelectedObject();

			if (selectedObj != null && selectedObj instanceof IBarrier) {

				List<Point> pointsList = ((AbstractBarrier) selectedObj).getPoints();

				int k = pointsList.size();

				for (int i = 0; i < k; i++) {

					if (pointsList.get(i).distance(point) < 10) {

						canvasPanel.setSelectedPointIndex(i);

						break;

					}
				}
			}
		}
			break;
		}
	}

	private void doAddEllipse(Point point) {
		// TODO Auto-generated method stub
		// 添加圆形事件
		if (canvasPanel.getTmpPointList().size() < 1) {
			canvasPanel.addTempPoint(point);
		} else {
			canvasPanel.addTempPoint(point);
			canvasPanel.addEllipse();
		}
	}

	private void doAddRectCase(Point point) {
		// TODO Auto-generated method stub
		// 添加矩形事件
		if (canvasPanel.getTmpPointList().size() < 1) {
			canvasPanel.addTempPoint(point);
		} else {
			canvasPanel.addTempPoint(point);
			canvasPanel.addRect();
		}
	}

	private void doAddLineCase(int clickCount, Point point) {
		// TODO Auto-generated method stub
		switch (clickCount) {
		case 1:
			canvasPanel.addTempPoint(point);
			break;
		case 2:
			canvasPanel.addLine();
			break;
		default:
			break;
		}
	}

	private void doPopUpMenuEvent(Point p) {
		// TODO Auto-generated method stub
		// 当右键点击选中的设备时，显示弹出式菜单以修改设备的部分属性。
		Object selectedObj = canvasPanel.getSelectedObject();

		if (selectedObj != null && selectedObj instanceof AbstractDevice) {
			deviePopUpMenu.show(canvasPanel, p.x, p.y);
		}
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		super.mouseMoved(arg0);

		if (canvasPanel.getCanvasModel() == null) {
			return;
		}

		Point point = arg0.getPoint();

		double roomPercent = canvasPanel.getCanvasModel().getRoomPercent();

		point.setLocation(point.getX() / roomPercent, point.getY() / roomPercent);

		switch (listenerCommand) {

		case ADDLINE: {
			canvasPanel.setMovePoint(point);
		}
			canvasPanel.repaint();
			break;
		case ADDCURVE: {
			canvasPanel.setMovePoint(point);
		}
			canvasPanel.repaint();
			break;
		case ADDRECT: {
			canvasPanel.setMovePoint(point);
		}
			canvasPanel.repaint();
			break;
		case ADDELLIPSE: {
			canvasPanel.setMovePoint(point);
		}
			canvasPanel.repaint();
			break;
		default:
			break;
		}

	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		super.mousePressed(e);
		if (canvasPanel.getCanvasModel() == null) {
			return;
		}
		if (canvasPanel.getSelectedObject() == null) {
			return;
		}

		Point point = e.getPoint();

		double roomPercent = canvasPanel.getCanvasModel().getRoomPercent();

		point.setLocation(point.getX() / roomPercent, point.getY() / roomPercent);

		oldPoint = point;
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		super.mouseDragged(e);

		switch (listenerCommand) {
		case NONE: {
			if (canvasPanel.getSelectedObject() == null) {
				return;
			}

			Point point = e.getPoint();

			double roomPercent = canvasPanel.getCanvasModel().getRoomPercent();

			point.setLocation(point.getX() / roomPercent, point.getY() / roomPercent);

			newPoint = point;

			double deltax = newPoint.getX() - oldPoint.getX();

			double deltay = newPoint.getY() - oldPoint.getY();

			if (canvasPanel.getSelectedPointIndex() != -1) {
				// 拖拽的是点
				((AbstractBarrier) canvasPanel.getSelectedObject()).drag(deltax, deltay,
						canvasPanel.getSelectedPointIndex());
			} else {

				if (canvasPanel.getSelectedObject() instanceof AbstractDevice) {
					// 拖拽的是设备

					((AbstractDevice) canvasPanel.getSelectedObject()).drag(deltax, deltay);

				} else if (canvasPanel.getSelectedObject() instanceof AbstractBarrier) { // 拖拽的是线

					((AbstractBarrier) canvasPanel.getSelectedObject()).drag(deltax, deltay);
				}

			}

			if (canvasPanel.validatePoint(newPoint)) {

				canvasPanel.setTipPoint(newPoint);
			}
			oldPoint = newPoint;
		}
			canvasPanel.repaint();
			break;

		default:
			break;
		}

	}

	public ListenerCommand getListenerCommand() {
		return listenerCommand;
	}

	public void setListenerCommand(ListenerCommand listenerCommand) {
		this.listenerCommand = listenerCommand;
		canvasPanel.clearTempDatas();
		switch (listenerCommand) {
		case NONE:
			infoBarPanel.setInfo(PlannerUtil.getString("Click device or barrier,Double click one point,You can drag it"));
			break;
		case ADDDEVICE:
			infoBarPanel.setInfo(PlannerUtil.getString("Click canvas to add one device,Right click to quit"));
			break;
		case ADDLINE:
			infoBarPanel
					.setInfo(PlannerUtil.getString("Click canvas to draw a line,Double click to finish,Right click to quit"));
			break;
		case ADDCURVE:
			infoBarPanel
					.setInfo(PlannerUtil.getString("Click canvas to draw a curve,Double click to finish,Right click to quit"));
			break;
		case ADDRECT:
			infoBarPanel.setInfo(
					PlannerUtil.getString("Click canvas to draw a rect,two points make a rect barrier,double click to quit"));
			break;
		case ADDELLIPSE:
			infoBarPanel.setInfo(PlannerUtil.getString(
					"Click canvas to draw a ellipse,two points make a ellipse barrier,double click to quit"));
			break;
		default:
			break;
		}
		canvasPanel.repaint();
	}

	public enum ListenerCommand {
		NONE, ADDDEVICE, ADDLINE, ADDRECT, ADDELLIPSE, ADDCURVE;
	}
}
